package team.zero.lemon.module.workflow.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team.zero.lemon.common.exception.CustomException;
import team.zero.lemon.common.service.CrudService;
import team.zero.lemon.module.workflow.dao.IFormDao;
import team.zero.lemon.module.workflow.entity.ActivityForm;
import team.zero.lemon.module.workflow.entity.Form;
import team.zero.lemon.module.workflow.entity.FormDefinition;
import team.zero.lemon.module.workflow.entity.FormDefinitionData;
import team.zero.lemon.module.workflow.entity.Parameter.FormParameter;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by Bo on 2016/10/24.
 */
@Service
public class FormService extends CrudService<IFormDao, Form> {
    @Autowired
    private FormDefinitionService definitionService;
    @Autowired
    private ActivityFormService activityFormService;

    @Autowired
    private FormDefinitionDataService definitionDataService;


    @Transactional
    public int SaveForm(FormParameter formParameter) {
        try {
            formParameter.getDeleteObj().forEach(a -> {
                if ("form".equals(a.getType() )) {
                    Form form = new Form();
                    form.setId(a.getId());
                    form.setInsert(false);
                    deleteLogic(form);
                } else {
                    FormDefinition formDefinition = new FormDefinition();
                    formDefinition.setId(a.getId());
                    formDefinition.setInsert(false);
                    definitionService.deleteLogic(formDefinition);
                }
            });
            return saveDefinition(formParameter.getListForm());
        } catch (Exception ex) {
            throw new CustomException(ex);
        }
    }

    @Transactional
    public int saveDefinition(List<Form> formlist) {
        for (Form form : formlist) {
            int id = save(form);
            if (!form.isInsert())
                id = form.getId();
            if (form.getActivityForms() != null) {
                activityFormService.deleteByFormId(id);
                for (ActivityForm activityForm : form.getActivityForms()) {
                    activityForm.setFormId(id);
                    activityFormService.save(activityForm);
                }
            }

            if (form.getFormDefinition() != null)
                for (FormDefinition definition : form.getFormDefinition()) {
                    definition.setFormId(id);
                    int defId = definitionService.save(definition);

                    if (definition.getDefinitionData() != null) {
                        if (!definition.isInsert())
                            defId = definition.getId();
                        FormDefinitionData formDefinitionData = definition.getDefinitionData();
                        formDefinitionData.setDefinitionId(defId);
                        formDefinitionData.setInsert(definition.isInsert());
                        definitionDataService.save(formDefinitionData);
                    }
                }
            for (Form subForm : form.getSubform()) {
                subForm.setParentId(id);
            }
            saveDefinition(form.getSubform());
        }
        return 1;


    }


    public List<Form> findFormbyTemplate(Integer templateId) {
        try {
            List<Form> allForm = dao.findFormbyTemplate(templateId);
            List<Form> result = new ArrayList<Form>();

            allForm.forEach(form -> {
                form.setFormDefinition(definitionService.findByFormId(form.getId()));
                for (FormDefinition definition : form.getFormDefinition()) {
                    if ("select".equals(definition.getTagName()) || "radio".equals(definition.getTagName()) || "check".equals(definition.getTagName()))
                        definition.setDefinitionData(definitionDataService.findByDefinitionId(definition.getId()));
                }


                if (form.getParentId() == null) {
                    result.add(form);
                }
                form.setActivityForms(activityFormService.findByFormId(form.getId()));
            });


            for (Form form : result) {
                List<Form> subForm = allForm.stream().filter(a -> form.getId().equals(a.getParentId())).collect(Collectors.toList());
                if (subForm.size() > 0) {
                    form.setSubform(subForm);
                }
            }
            return result;
        } catch (Exception ex) {
            throw new CustomException(ex);
        }
    }

    public List<Form> findFormbyParent(Integer parentId) {
        return dao.findFormbyParent(parentId);
    }
}
